查看原文
其他

精通Linux系列十六:为什么有个进程kill不掉?

拾叁 更AI 2023-10-21

精通Linux系列点击关注公众号,AI&编程干货及时送达   


控制进程

命令含义
kill结束一个进程(或向其发送一个信号)。
timeout杀掉运行过久的命令。
nice以特定的优先级调用程序。
renice在进程运行时改变其优先级。
flock使用锁确保一次只有一个进程的副本在运行。

进程开始之后,它们可以被停止,重新启动,杀死和重新优先化。我们在 [“Shell Job Control”] 中讨论了一些由 shell 处理的这些操作。现在我们来讨论杀死和重新优先化。

kill

stdin  stdout  - file  -- opt  --help  --version

kill [选项] [进程ID]

kill 命令向进程发送信号。这可以结束进程(默认行为),中断它,挂起它,使其崩溃,等等。你必须是进程的所有者,或者是超级用户,才能影响它。例如,要终止进程 13243,运行:

 kill 13243

如果这不起作用 - 有些程序在不终止的情况下捕获此信号 - 添加 -KILL 或者(等同的)-9 选项:

 kill -KILL 13243

然而,这对于程序来说并不是一个正常的退出,它可能在死亡时留下分配的资源(或引发其他不一致性)。

如果你不知道进程的 PID,运行 ps 并检查输出:

 ps -uax | grep emacs

或者更好的是,试试 pidof 命令,它可以根据其名称查找并打印进程的 PID:

 pidof emacs
8374

现在你可以在一行中只通过程序名杀死进程,使用 shell 反引号来执行 pidof

 kill `pidof emacs`

或者使用 killall 命令杀死给定程序的所有进程:

 killall emacs

除了文件系统中的 kill 程序(通常是 /bin/kill),大多数 shell 都有内置的 kill 命令,但是它们的语法和行为不同。然而,它们都支持以下用法:

 kill -N PID
 kill -NAME PID

其中 N 是信号数字,*NAME* 是没有前导“SIG”的信号名称(例如,使用 -HUP 发送 SIGHUP 信号)。要查看 kill 发送的所有信号的完整列表,运行 kill -l,尽管它的输出取决于你正在运行哪个 kill。要查看信号的描述,运行 man 7 signal

timeout

stdin  stdout  - file  -- opt  --help  --version

timeout [选项] 秒数 命令...

timeout 命令为运行另一个程序设置时间限制,单位为秒。如果程序运行的时间超过限制,timeout 会杀死它。作为示范,这是一个 sleep 命令,它应该运行一分钟,但在 3 秒后被杀死:

 sleep 60               运行 60 
 timeout 3 sleep 60      3 秒后被杀死

作为一个更实际的例子,从你的 MP3 集合中播放一小时的音乐,然后停止:

 timeout 3600 mplayer *.mp3

有用的选项

-s *信号*发送一个除默认(TERM)之外的信号。选择项与 kill -l 列出的相同。
-k *秒数*如果程序在第一次信号后还没有死,等待这么多秒后发送一个致命的 KILL 信号。

nice

stdin  stdout  - file  -- opt  --help  --version

nice [-级别] 命令行

在调用系统密集型程序时,你可以通过降低其优先级来对其他进程(和用户)友好。这就是 nice 命令的作用:它为进程设置一个 nice 级别(一定量的“友善度”),以便它在 Linux 进程调度器中得到较少的关注。[17] 这是一个将大任务设置为在 nice 级别 7 运行的例子:

 nice -7 sort hugefile > outfile

如果你运行 nice 但没有指定级别,将使用 10。普通进程(没有使用 nice 运行)在零级别运行,你可以通过运行 nice 并不带任何参数来查看:

 nice
0

超级用户也可以降低 nice 级别,增加进程的优先级:

 sudo nice --10 myprogram

要查看你的任务的 nice 级别,使用 ps 并查看“NI”列:

 ps -o pid,user,args,nice

renice

stdin  stdout  - file  -- opt  --help  --version*

renice [-n N] [选项] PID

nice 命令可以在给定的 nice 级别下调用一个程序,renice 则可以改变一个已经在运行的进程的 nice 级别。这里我们将进程 28734 的 nice 级别增加 5:

 renice -5 -28734

作为一个快速(但微不足道)的测试,你可以创建一个仅休眠2分钟的进程,将其在后台运行,并更改其优先级:

 sleep 120 &
 pidof sleep
2673
 renice -5 -2673
2673 (进程 ID) 旧优先级 0,新优先级 5

普通用户可以提高他们自己进程的 nice 级别,而超级用户还可以降低它(提高优先级)并可以操作任何进程。有效范围是 −20 到 +20,但要避免使用高的负数,否则你可能会干扰到关键的系统进程。

有用的选项

-p pid影响给定的进程 ID。你可以省略 -p,只提供一个 PID(renice -n 5 28734)。
-u username影响由给定用户拥有的所有进程。

flock

stdin  stdout  - file  -- opt  --help  --version

flock  [options] lockfile command...

你是否需要确保一次只有一个程序的副本在你的计算机上运行?例如,如果你每小时使用 rsync 命令运行自动备份,那么之前的备份可能仍在运行,当下一个备份启动时。flock 命令解决了这种问题。它阻止一个命令(例如备份脚本)与自身并发运行。如果你尝试一次运行该命令的两个副本,第二个将失败。例如,当与 flock 一起运行时,此 rsync 命令将立即失败,如果同一命令的另一个实例已经在运行:

 flock -/tmp/mylock rsync ...

要查看 flock 的实际效果,请打开两个 shell 窗口,并在每个 shell 中依次运行以下命令(我们将使用 sleep 命令作为演示,它只是等待给定的秒数):

 flock -/tmp/mylock sleep 60

第一个命令将运行,第二个将立即终止。这两个命令不必完全相同,但它们必须引用第一个参数中相同的 *lockfile*。这可以是任何文件或目录的名称,flock 将其视为一个唯一标记,以防止其他命令的运行。例如,如果你在一个 shell 中运行相同的 sleep 命令,并在另一个中使用相同的锁文件运行不同的命令,比如 ls

 flock -/tmp/mylock ls

第二个仍将失败。但如果你提供不同的锁文件,两个命令都将运行。

有用的选项

-n如果另一个命令已经在运行,立即失败。
-w *N*如果另一个命令已经在运行,等待 N  秒后失败。
-s使用共享锁代替独占锁。使用此选项时,你可以同时运行多个命令,但如果省略该选项,flock 将失败。这对允许有限数量的命令同时运行很有用。

推荐阅读

··································

你好,我是拾叁,7年开发老司机、互联网两年外企5年。怼得过阿三老美,也被PR comments搞崩溃过。这些年我打过工,创过业,接过私活,也混过upwork。赚过钱也亏过钱。一路过来,给我最深的感受就是不管学什么,一定要不断学习。只要你能坚持下来,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你还没什么方向,可以先关注我,这里会经常分享一些前沿资讯和编程知识,帮你积累弯道超车的资本。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存